﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using AdaptiveAgents.Tools;

namespace AdaptiveAgents.Formulas
{
    class FindTheBestAgentTool
    {        
        private List<Record> m_lDataBase;
        private List<PrintRecord> m_prPrintArray;


        public FindTheBestAgentTool()
        {            
            m_lDataBase = new List<Record>();
            m_prPrintArray = new List<PrintRecord>();
        }
        
        public void addRecord(Record rec)
        {
            m_lDataBase.Add(rec);
        }

        public void clear()
        {
            m_lDataBase.Clear();            
            m_prPrintArray.Clear();
        }

        public void solveRecord(Record rec,int gameNumber)
        {
            ProbabilitiesMatrix regularMatrix, matrixForAgent0, matrixForAgent1, matrixForAgent2;
            double[] vectorProbabilitiesForAgent1;
            double[] vectorProbabilitiesForAgent2;
            double[] vectorProbabilitiesForAgent0;
            double[] vectorProbabilitiesForRegular;
           

            FirstPartOfCheckingTool tool = new FirstPartOfCheckingTool(rec);
            SecondPartOfCheckingTool tool2 = new SecondPartOfCheckingTool();

            PrintRecord pRec = new PrintRecord();
            PrintRecord pRec0 = new PrintRecord();
            PrintRecord pRec1 = new PrintRecord();
            PrintRecord pRec2 = new PrintRecord();            

            tool.solve();
            regularMatrix = tool.getSolution();

            matrixForAgent0 = regularMatrix.clone();
            matrixForAgent1 = regularMatrix.clone();
            matrixForAgent2 = regularMatrix.clone();

            matrixForAgent0.setProbability0to0(1);
            matrixForAgent0.setProbability0to1(0);
            matrixForAgent0.setProbability0to2(0);

            matrixForAgent1.setProbability0to0(0);
            matrixForAgent1.setProbability0to1(1);
            matrixForAgent1.setProbability0to2(0);

            matrixForAgent2.setProbability0to0(0);
            matrixForAgent2.setProbability0to1(0);
            matrixForAgent2.setProbability0to2(1);

            vectorProbabilitiesForRegular = tool2.solveRecord(regularMatrix, rec);
            PrintRecord regular = new PrintRecord(rec, vectorProbabilitiesForRegular, gameNumber, -1);
            regular.setAverageProfit(calculateAverageProfit(rec, vectorProbabilitiesForRegular));

            vectorProbabilitiesForAgent0 = tool2.solveRecord(matrixForAgent0, rec);
            PrintRecord special0 = new PrintRecord(rec, vectorProbabilitiesForAgent0, gameNumber, 0);
            special0.setAverageProfit(calculateAverageProfit(rec, vectorProbabilitiesForAgent0));

            vectorProbabilitiesForAgent1 = tool2.solveRecord(matrixForAgent1, rec);
            PrintRecord special1 = new PrintRecord(rec, vectorProbabilitiesForAgent1, gameNumber, 1);
            special1.setAverageProfit(calculateAverageProfit(rec, vectorProbabilitiesForAgent1));

            vectorProbabilitiesForAgent2 = tool2.solveRecord(matrixForAgent2, rec);
            PrintRecord special2 = new PrintRecord(rec, vectorProbabilitiesForAgent2, gameNumber, 2);
            special2.setAverageProfit(calculateAverageProfit(rec, vectorProbabilitiesForAgent2));

            m_prPrintArray.Add(regular);
            m_prPrintArray.Add(special0);
            m_prPrintArray.Add(special1);
            m_prPrintArray.Add(special2);

        }

        public void solveDataBase()
        {
            for (int i = 0; i < m_lDataBase.Count; ++i)
            {
                solveRecord(m_lDataBase[i], i); 
            }
        }

        public void printResultToCSVFile()
        {
            DataTable printOut = new DataTable("Result_Of_Find_The_Best_Agent_Tool");
            DataRow row;
            PrintRecord tempRec;

            DataColumn cln = new DataColumn("Game_Number", typeof(double));
            printOut.Columns.Add(cln);
            cln = new DataColumn("Agent_Number", typeof(double));
            printOut.Columns.Add(cln);
            cln = new DataColumn("Competence2", typeof(double));
            printOut.Columns.Add(cln);
            cln = new DataColumn("Competence1", typeof(double));
            printOut.Columns.Add(cln);
            cln = new DataColumn("Competence0", typeof(double));
            printOut.Columns.Add(cln);
            cln = new DataColumn("Epsilon2", typeof(double));
            printOut.Columns.Add(cln);
            cln = new DataColumn("Epsilon1", typeof(double));
            printOut.Columns.Add(cln);
            cln = new DataColumn("Epsilon0", typeof(double));
            printOut.Columns.Add(cln);            
            cln = new DataColumn("CalculateGradePerRound", typeof(double));
            printOut.Columns.Add(cln);


            for (int i = 0; i < m_prPrintArray.Count; ++i)
            {
                row = printOut.NewRow();
                tempRec = m_prPrintArray[i];

                row["Game_Number"] = tempRec.m_iGameNumber;
                row["Agent_Number"] = tempRec.m_iAgentNumber;

                row["Competence0"] = tempRec.m_aiAgent0.getCompetence();
                row["Competence1"] = tempRec.m_aiAgent1.getCompetence();
                row["Competence2"] = tempRec.m_aiAgent2.getCompetence();

                row["Epsilon0"] = tempRec.m_aiAgent0.getEpsilon();
                row["Epsilon1"] = tempRec.m_aiAgent1.getEpsilon();
                row["Epsilon2"] = tempRec.m_aiAgent2.getEpsilon();               

                row["CalculateGradePerRound"] = tempRec.getAverageProfit();            

                printOut.Rows.Add(row);
            }
            String stamp = DateTime.Now.ToString("yyyy.MM.dd-HH.mm.ss");
            CSVprinter.WriteToCSV("Result_Of_Find_The_Best_Agent_Tool_" + stamp + ".csv", printOut);
        }

        private double calculateAverageProfit(Record rec, double[] vec)
        {
            if (vec[0] + vec[1] + vec[2] == 1)
            {
                return rec.getCompetence(0) * vec[0] + rec.getCompetence(1) * vec[1] + rec.getCompetence(2) * vec[2];
            }

            return 0;
        }
















    }
}
